using Mongoc;
using Bson;

void main() {
    var loop = new MainLoop();
    //  var server = new HttpServer(new SocketService());
    //  server.set_request_handler(context => handleRequest(context));
    //  server.socketService.add_inet_port(7000, null);
    //  server.socketService.start();
    //  print("Server start successfully!\n");

    run();
    loop.run();
}

async void handleRequest(HttpContext context) throws Error {
    var person = new Person() {
        name = @"مۇختەر",
        age = 25,
        address = context.connection.socket.get_remote_address().to_string(),
        contacts = new string[] {"+861869013xxxx", "Dream-Labs"}
    };

    context.response.headers.add(new XPoweredBy("BlueBird http server"));

    if (context.request.path == "/home") yield context.response.write(new HtmlContent("<h1 style=\"color: red;\">Hello from vala<h1>"));
    else yield context.response.write(new JsonContent(person));
}



class Person: GLib.Object {
    public string name {get;set;}
    public uint8 age {get;set;}
    public string address {get;set;}
    public string[] contacts {get;set;}
}

class XPoweredBy : Header.HttpHeader<string> {
    public override string key { get; set; default = "X-Powered-By"; }
    public XPoweredBy(string server) { this.value = server;}
    public override string build () { return @"$key: $value";}
    public override void parse_value (string value){}
}


public async void delay(uint32 milliseconds) {
    var source = new TimeoutSource(milliseconds);
    source.set_callback(() => {
        delay.callback();
        return false;
    });
    source.attach();
    yield;
}

//  void run (){
//      Mongoc.init();
//      var uri = new Mongoc.Uri.for_host_port("mestane.cn", 27017) {
//          username = "root",
//          password = "Developer653125"
//      };
//      var client = new Client.from_uri(uri);
//      var dataBases = client.get_safe_database_names_with_opts();
//      foreach (var name in dataBases) {
//          print(name + "\n");
//      }
//      Mongoc.cleanup();

//      Task task = new Task(null, null, (source, task) => {
        
//      });
//  }

//  Bson.Bson generate_document() {
//      var doc = new Bson.Bson();
//      doc.append_utf8("name", -1, "مەردانجان");
//      doc.append_utf8("address", -1, "شىنجاڭ ئۈرۈمچى");
//      var time = new DateTime(new TimeZone.utc(), 1994, 03, 01, 0, 0, 0);
//      doc.append_date_time("birthday", -1, time.to_unix());
//      return doc;
//  }

async void run() {

    var num = 1;
    for (var a = 0; a < num; a++) {
        task_async.begin(new TaskId(){id = a}, (source, async_result) => {
            Person *_person = task_async.end(async_result);
            Person person = _person;
            num--;
            print(@"$(person.name): $(person.age)\n");
            if (num == 0) run.callback();
            delete _person;
        });
    }
    yield;
    print("Over all");
}

async Person task_async(TaskId id) {
    Person *value = null;
    var task = new Task(id, null, (source_object, task) => {
        value = task.propagate_pointer();
        print(value->name);
        task_async.callback();
    });
    task.run_in_thread(_task);
    yield;
    return value;
}
void _task(Task task, Object source_object, void *task_data, Cancellable? cancellable) {
    for (var a = 0; a < 100000000; a++) {

    }
    Person *person = new Person();;
    person->address = "China xinjiang";
    person->age = (source_object as TaskId).id;
    task.return_pointer(person, person->unref);
}

class TaskId : Object {
    public uint8 id {get;set;}
}